package com.rchou.sts.service.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.rchou.sts.domain.Student;
import com.rchou.sts.domain.StudentSummary;
import com.rchou.sts.repository.StudentRepository;
import com.rchou.sts.service.StudentService;

@Service("studentService")
@Repository
@Transactional
public class StudentServiceImpl implements StudentService
{
	private Log log = LogFactory.getLog(StudentServiceImpl.class);
	
	final static String ALL_STUDENT_NATIVE_QUERY =
			"select id, first_name, last_name, phone, version from student";
	
	@PersistenceContext
	private EntityManager em;
	
	@Autowired
	private StudentRepository studentRepository;

	@Transactional(readOnly=true)
	@Override
	public List<Student> findAll() 
	{
		log.info("Getting all students.");
		//List<Student> students = em.createNamedQuery("Student.findAll", Student.class).getResultList();
		List<Student> students = (List<Student>) studentRepository.findAll();
		return students;
	}

	@Transactional(readOnly=true)
	@Override
	public List<Student> finAllWithDetail() 
	{
		log.info("Getting all students with details.");
		List<Student> contacts = em.createNamedQuery("Student.findAllWithDetail", Student.class).getResultList();
		return contacts;
	}

	@Transactional(readOnly=true)
	@Override
	public Student findById(Long id) 
	{
		log.info("Getting student by id.");
		//TypedQuery<Student> query = em.createNamedQuery("Student.findById", Student.class);
		//query.setParameter("id", id);
		Student student = studentRepository.findOne(id);
		student.getLevels().size();
		//return query.getSingleResult();
		return student;
	}
	
	@Transactional(readOnly=true)
	@Override
	public List<StudentSummary> findAllSummary() 
	{
		log.info("Getting all students summary.");
		
		String sql = "SELECT new com.rchou.sts.domain.StudentSummary(s.firstName, s.lastName, s.phone, l.level) " + 
				"FROM Student s left join s.lvlHistories l ";
		List<StudentSummary> students = em.createQuery(sql).getResultList();				
		return students;
	}
	
	public Student save(Student student)
	{
		/*if (student.getId() == null)
		{ // Insert Student
			log.info("Inserting new student");
			em.persist(student);
		} else
		{ // Update Student
			log.info("Updating existing student");
			em.merge(student);
		}*/
		student = studentRepository.save(student);
		log.info("Student saved with id: " + student.getId());
		
		return student;
	}
	
	public void delete(Student student)
	{
		log.info("Deleteing Student with id: " + student.getId());
		//Student mergedStudent = em.merge(student);
		//em.remove(mergedStudent);
		studentRepository.delete(student); 
	}
	
	@Transactional(readOnly=true)
	public List<Student> findAllByNativeQuery() 
	{
		//return em.createNativeQuery(ALL_STUDENT_NATIVE_QUERY, Student.class).getResultList();
		return em.createNativeQuery(ALL_STUDENT_NATIVE_QUERY, "studentResult").getResultList();
	}
}
